#include <QTimer>
#include <QXmlAttributes>
#include <QXmlStreamAttribute>
#include <QXmlStreamAttributes>
#include <QPluginLoader>
#include <QCoreApplication>
#include <QDebug>

#include "WorkThreadManage/Hmiremotethreadmanage.h"
#include "uniontecsystemdll_global.h"
#include "Interface/PluginInterface/tecpluginremoteinterface.h"
#include "Interface/PluginInterface/kukateplugininterface.h"

HmiRemoteThread:: HmiRemoteThread(){
    if(this->pClientSocket == nullptr){
        this->pClientSocket = new QTcpSocket();
    }
    pClientSocket->connectToHost("127.0.0.1", 1205);
    connect(pClientSocket, SIGNAL(readyRead()), this, SLOT(RemoteDataRecv()));
    this->AskCommandTimer = new QTimer();
    connect(AskCommandTimer, SIGNAL(timeout()), this, SLOT(AskCommandTimerUpdate()));
    this->AskCommandTimer->start(50);
}

HmiRemoteThread::~HmiRemoteThread(){
    this->pClientSocket->close();
    if(this->pClientSocket != nullptr) delete this->pClientSocket;
    this->pClientSocket = nullptr;
    delete this->AskCommandTimer;
}

void HmiRemoteThread::AskCommandTimerUpdate(){
    QByteArray sendData;

    if(pClientSocket->state() == QAbstractSocket::ConnectedState){
        if(this->ptecPluginInstance != nullptr){
            this->ptecPluginInstance->BackendDataSend(sendData);
            this->pClientSocket->write(sendData);
        }
        else if(this->pkukatecPluginInstance != nullptr){
            this->pkukatecPluginInstance->BackendDataSend(sendData);
            this->pClientSocket->write(sendData);
        }
        else{
            sendData = "<Sender>TechController</Sender><TechController>NoTechPluginRunning</TechController>";
            this->pClientSocket->write(sendData);
        }
    }
}

void HmiRemoteThread::RemoteDataRecv(){
    QByteArray receiverawData;
    QXmlStreamReader mQXmlStreamReader;

    QString MessageSender;
    QString TecPluginStatus;
    QString TecPluginType;
    QString TecPluginName;

    receiverawData = this->pClientSocket->readAll();
    mQXmlStreamReader.addData(receiverawData);
    while(!mQXmlStreamReader.atEnd()){
        if(mQXmlStreamReader.isStartElement()){
            if(mQXmlStreamReader.name() == "Sender"){
                QString  tempQString;
                tempQString = (mQXmlStreamReader.readElementText());
                MessageSender = tempQString;
            }
            if(mQXmlStreamReader.name() == "Status"){
                QString  tempQString;
                tempQString = (mQXmlStreamReader.readElementText());
                TecPluginStatus = tempQString;
            }
            else if(mQXmlStreamReader.name() == "Type"){
                QString  tempQString;
                tempQString = (mQXmlStreamReader.readElementText());
                TecPluginType = tempQString;
            }
            else if(mQXmlStreamReader.name() == "Name"){
                QString  tempQString;
                tempQString = (mQXmlStreamReader.readElementText());
                TecPluginName = tempQString;
            }
        }
        mQXmlStreamReader.readNext();
    }
    mQXmlStreamReader.clear();
    if(MessageSender == "HMISYSTEM"){
        if(TecPluginStatus == "New"){
            if(TecPluginType == "KUKAPlugin"){
                if(this->pkukatecPluginInstance == nullptr){
                    QPluginLoader pluginLoader(QCoreApplication::applicationDirPath() + "/" + TecPluginName);
                    this->pkukatecPluginInstance = qobject_cast<kukatecPluginInterface*>(pluginLoader.instance());
                    if(this->pkukatecPluginInstance != nullptr){
                        this->pBackUdpThread->KUKAPluginInstanceConnect(this->pkukatecPluginInstance);
                        this->pBackTcpThread->KUKAPluginInstanceConnect(this->pkukatecPluginInstance);
                        this->pHmiThread->KUKAPluginInstanceConnect(this->pkukatecPluginInstance);
                        this->pBackTcpThread->PluginStatusTransitions(ENUM_PluginStatus::Init);
                        this->pBackUdpThread->PluginStatusTransitions(ENUM_PluginStatus::Init);
                        qDebug()<<"RemoteThread::RemoteDataRecv() - New KUKAPlugin";
                        UnionTecSystemMessageBox(MessageType::Message,"RemoteThread::RemoteDataRecv() - New KUKAPlugin");
                    }
                }
            }
            else if(TecPluginType == "NormalPlugin"){
                if(this->ptecPluginInstance == nullptr){
                    QPluginLoader pluginLoader(QCoreApplication::applicationDirPath() + "/" + TecPluginName);
                    this->ptecPluginInstance = qobject_cast<tecPluginInterface*>(pluginLoader.instance());
                    if(this->ptecPluginInstance != nullptr){
                        this->pBackTcpThread->PluginInstanceConnect(this->ptecPluginInstance);
                        this->pHmiThread->PluginInstanceConnect(this->ptecPluginInstance);
                        this->pBackTcpThread->PluginStatusTransitions(ENUM_PluginStatus::Init);
                        qDebug()<<"RemoteThread::RemoteDataRecv() - New NormalPlugin";
                        UnionTecSystemMessageBox(MessageType::Message,"RemoteThread::RemoteDataRecv() - New NormalPlugin");

                    }
                }
            }
        }
        else if(TecPluginStatus == "Run"){
            if(this->ptecPluginInstance != nullptr){
                this->pBackTcpThread->PluginStatusTransitions(ENUM_PluginStatus::Running);
                this->ptecPluginInstance->BackendDataRecv(receiverawData);
            }
            else if(this->pkukatecPluginInstance != nullptr){
                this->pBackTcpThread->PluginStatusTransitions(ENUM_PluginStatus::Running);
                this->pBackUdpThread->PluginStatusTransitions(ENUM_PluginStatus::Running);
                this->pkukatecPluginInstance->BackendDataRecv(receiverawData);
            }
        }
        else if(TecPluginStatus == "Stop") {
            this->pBackTcpThread->PluginStatusTransitions(ENUM_PluginStatus::Stop);
            this->pBackUdpThread->PluginStatusTransitions(ENUM_PluginStatus::Stop);
        }
        else if(TecPluginStatus == "Pause"){
            this->pBackTcpThread->PluginStatusTransitions(ENUM_PluginStatus::Pause);
            this->pBackUdpThread->PluginStatusTransitions(ENUM_PluginStatus::Pause);
        }
        else if(TecPluginStatus == "Delete"){
            if(this->ptecPluginInstance != nullptr){
                this->pBackTcpThread->PluginStatusTransitions(ENUM_PluginStatus::Delete);
                this->pHmiThread->PluginInstanceLogOut();

                this->ptecPluginInstance = nullptr;
            }
            else if(this->pkukatecPluginInstance != nullptr){
                this->pBackTcpThread->PluginStatusTransitions(ENUM_PluginStatus::Delete);
                this->pBackUdpThread->PluginStatusTransitions(ENUM_PluginStatus::Delete);
                this->pHmiThread->PluginInstanceLogOut();
                this->pkukatecPluginInstance = nullptr;
            }
        }
        else{
        }
    }
    else if(MessageSender == "TECHPLUGIN"){
        if(this->ptecPluginInstance != nullptr){
            this->ptecPluginInstance->BackendDataRecv(receiverawData);
        }
        else if(this->pkukatecPluginInstance != nullptr){
            this->pkukatecPluginInstance->BackendDataRecv(receiverawData);
        }
        else{
        }
    }
}
